package com.sj.purchase.modules.cost.service;

import com.sj.purchase.modules.cost.config.task.UploadExcel;
import com.sj.purchase.modules.cost.config.task.compute.ComputeTaskManager;
import com.sj.purchase.modules.cost.config.task.synchronizedata.SyncTaskManager;
import com.sj.purchase.modules.cost.domain.SucTask;
import com.sj.purchase.modules.cost.event.AfterSyncEvent;
import com.sj.purchase.modules.cost.publisher.CustomPublisher;
import com.sj.purchase.modules.cost.repository.SucTaskRepository;
import com.sj.purchase.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 同步差异
 * create by MaJinGe on 2017-11-14
 */
@Service
public class SucTaskServiceImpl implements SucTaskService {

    @Autowired
    private SucTaskRepository repository;

    @Autowired
    private SyncTaskManager syncTaskManager;

    @Autowired
    private ComputeTaskManager computeTaskManager;

    @Autowired
    private CustomPublisher publisher;

    @Autowired
    private UploadExcel uploadExcel;

    /**
     * 保存同步成功的任务
     * @param taskType
     * @param day
     */
    @Override
    public void save(SucTask.TaskType taskType, Date day) {
            repository.save(new SucTask(taskType,day));
            Long count = repository.countByTaskDay(day);
            if (count == 5 && taskType.getIsSync()) {
                publisher.publishEvent(new AfterSyncEvent(this, day));
            }
            if (count==7){
                uploadExcel.setDay(day);
                uploadExcel.outOrder();//出库单成本明细
                uploadExcel.skuStock();//sku出入库查询
                uploadExcel.orderCost();//订单利润
                uploadExcel.beginStockReport();//进销存报表-->期初
                uploadExcel.endStockReport();//进销存报表-->期末
            }
    }

    /**
     * 显示未同步的数据
     */
    @Override
    public List<SucTask> findByDate(Date begin, Date end) {
        List<SucTask> sucTaskList = this.allDataByDateScope(begin,end);
        List<SucTask> sucTasks = repository.findByTaskDayBetweenAndTaskDay(begin,end);  //获取已经同步的数据
        sucTaskList.removeAll(sucTasks);  //获取没有执行同步任务的数据
        return sucTaskList;
    }

    /**
     * 获取某个日期段内所有的同步数据
     * @param begin
     * @param end
     * @return
     */
    private List<SucTask> allDataByDateScope(Date begin, Date end){
        List<SucTask> sucTaskList = new ArrayList<>();
        List<Date> getDate = this.getDate(begin,end); //日期段
        if (getDate.size()==0){                     //只有一天
                sucTaskList = this.allData(begin);
        }else {
            for (Date date:getDate){                  //日期范围
                sucTaskList.addAll(this.allData(date));
            }
        }
        return sucTaskList;
    }

    private List<SucTask> allData(Date date){
        List<SucTask> sucTaskList = new ArrayList<>();
        SucTask.TaskType[] taskTypes = SucTask.TaskType.values();
        for (SucTask.TaskType taskType : taskTypes) {
            if (taskType.getIsSync() == true&&!taskType.getName().equals("同步库存")) {
                SucTask sucTask = Optional.ofNullable(repository.findByTaskTypeAndTaskDay(taskType, date)).orElseGet(() -> new SucTask(taskType,date));
                sucTaskList.add(sucTask);
            }
        }
        return sucTaskList;
    }

    /**
     * 同步数据
     */
    @Override
    public void syncData(SucTask.TaskType taskType, Date date) {
        if (taskType.getIsSync()) {
            if(!taskType.equals(SucTask.TaskType.SYNC_STOCK)){
                syncTaskManager.runTask(taskType,date);
            }
        } else {
            computeTaskManager.runTask(taskType,date);
        }
    }

    /**
     *获得查询日期段的每一天
     */
    private List<Date> getDate(Date begin,Date end){
        List<Date> dateList = new ArrayList<>();
        Long daySum = (end.getTime()-begin.getTime())/(24*60*60*1000);
        for (int i=0;i<daySum;i++){
            dateList.add(DateUtils.addDays(begin,i));
        }
        return dateList;
    }
}
